package com.xhy.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xhy.annotation.RequiredToken;
import com.xhy.constant.RedisPrefix;
import com.xhy.entity.Category;
import com.xhy.entity.User;
import com.xhy.entity.Video;
import com.xhy.entity.vo.MsgVO;
import com.xhy.feignclient.CategoryFeignService;
import com.xhy.feignclient.VideoFeignService;
import com.xhy.service.IUserService;
import com.xhy.utils.ImageUtils;
import com.xhy.utils.OSSUtils;
import lombok.SneakyThrows;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.velocity.shaded.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 用户 前端控制器
 * </p>
 *
 * @author xhy
 * @since 2022-08-30
 */
@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private IUserService userService;
    @Resource
    private RedisTemplate<String,Object> redisTemplate;
    @Autowired
    private VideoFeignService videoFeignService;
    @Autowired
    private CategoryFeignService categoryFeignService;
    @PostMapping("/tokens")
    public Map<String,String> login(@RequestBody MsgVO msgVO, HttpSession session){
//        1.到redis里面获取该手机号对应的验证码跟用户输入的验证码是否一致。
        String redisVerify=(String)redisTemplate.opsForValue().get(RedisPrefix.PHONE_KEY+msgVO.getPhone());
        if(StringUtils.equals(redisVerify,msgVO.getCaptcha())){
//        2.根据手机号到user表里面查询user对象，看数据库里面是否有该用户
            QueryWrapper<User> wrapper = new QueryWrapper<>();
            wrapper.eq("phone",msgVO.getPhone());
            User user = userService.getOne(wrapper);
//        3.没有就注册，有了就登录
            if(ObjectUtils.isEmpty(user)){
//        4.注册就是往数据库里面插入一个user对象。
                user =new User();
                user.setName(msgVO.getPhone());
                user.setAvatar(ImageUtils.getPhoto());
                user.setIntro("这个人很懒，什么都没有留下。。。");
                user.setPhone(msgVO.getPhone());
                user.setCreatedAt(LocalDateTime.now());
                user.setUpdatedAt(LocalDateTime.now());
                user.setFollowersCount(0);
                user.setFollowingCount(0);
                user.setPhoneLinked(true);
                user.setWechatLinked(false);
                userService.save(user);
            }

            //5.登录就是获取到sessionId，放入到redis里面key为sessionId，值为user对象。
            String token = session.getId();
            redisTemplate.opsForValue().set(RedisPrefix.USER_TOKEN_KEY+token,user,30, TimeUnit.MINUTES);
            //6.把sessionId放入到map里面返回
            Map<String,String> resultMap = new HashMap<>();
            resultMap.put("token",token);
            return resultMap;
        }else{
            throw new RuntimeException("验证码不一致。。。");
        }
    }

    @GetMapping("/user")
    @RequiredToken
    public User userinfo(String token){
        User user = (User) redisTemplate.opsForValue().get(RedisPrefix.USER_TOKEN_KEY + token);
        if(ObjectUtils.isEmpty(user)){
            throw new RuntimeException("token异常。。。");
        }
        return user;
    }
    @DeleteMapping("tokens")
    public void logout(String token) {
        //根据TokenKey在redis中删除
        redisTemplate.delete(RedisPrefix.USER_TOKEN_KEY+token);
    }

    @PatchMapping("user")
    @RequiredToken
    public User user(@RequestBody User user, HttpServletRequest request) {
        //1.获取token信息
        String token = (String) request.getAttribute("token");
        //2.获取原始用户信息
        User userOld = (User) request.getAttribute("user");
        //3.是否修改手机号
        if (!StringUtils.isEmpty(user.getPhone())) {
            //修改手机号
            String phoneKey = RedisPrefix.PHONE_KEY + user.getPhone();
            if (!redisTemplate.hasKey(phoneKey)) {
                throw new RuntimeException("提示:验证码已过期!");
            }
            String redisCaptcha = redisTemplate.opsForValue().get(phoneKey).toString();//获取redis验证码
            if (!StringUtils.equals(redisCaptcha, user.getCaptcha())) {
                throw new RuntimeException("提示:验证码输入错误!");
            }
            userOld.setPhone(user.getPhone());
        }
        //4.未修改手机号
        if (!StringUtils.isEmpty(user.getName())) {
            userOld.setName(user.getName());
        }
        if (!StringUtils.isEmpty(user.getIntro())) {
            userOld.setIntro(user.getIntro());
        }
        //5.更新用户信息
        userService.updateById(userOld);
        //6.更新redis中原始用户信息
        redisTemplate.opsForValue().set(RedisPrefix.USER_TOKEN_KEY + token, userOld, 30, TimeUnit.MINUTES);
        return userOld;
    }

    //发布视频的方法
    @SneakyThrows
    @PostMapping("/user/videos")
    @RequiredToken
    public Video publishVideo(MultipartFile file, Video video, Integer category_id, HttpServletRequest request){
        //1.使用工具OSSUtils把file对象保存到阿里云，返回uri
        String originalFilename = file.getOriginalFilename();//获取到用户上传这个文件的原始文件名。
        String newName = UUID.randomUUID().toString() +"."+ FilenameUtils.getExtension(originalFilename);
        String ossAddr = OSSUtils.upload(file.getInputStream(), "videos", newName);
        //2.把video保存起来。通过openfeign远程调用视频服务
        //远程调用类别的服务，通过id找出类别名字，赋值给video对象
        Category category = categoryFeignService.selectById(category_id);
        video.setCategory(category.getName());

        video.setCover(ossAddr+"?x-oss-process=video/snapshot,t_10000,f_jpg,w_0,h_0,m_fast,ar_auto");
        video.setCategoryId(category_id);
        video.setLink(ossAddr);
        User user = (User)request.getAttribute("user");
        video.setUid(user.getId());
        video.setUploader(user.getName());
        videoFeignService.addVideo(video);

        //3.响应信息
        return video;
    }
    @GetMapping("/selectOne/{id}")
    public User selectById(@PathVariable("id") Integer id){
        return userService.getById(id);
    }
}

